package Leetcode.数组字符串;

/**
 * @ClassName 压缩字符串
 * @since: 2023/8/5 15:33
 * @auth: kirito
 * @description:
 * 给你一个字符数组 chars ，请使用下述算法压缩：
 *
 * 从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符 ：
 *
 * 如果这一组长度为 1 ，则将字符追加到 s 中。
 * 否则，需要向 s 追加字符，后跟这一组的长度。
 * 压缩后得到的字符串 s 不应该直接返回 ，需要转储到字符数组 chars 中。
 * 需要注意的是，如果组长度为 10 或 10 以上，则在 chars 数组中会被拆分为多个字符。
 *
 * 请在 修改完输入数组后 ，返回该数组的新长度。
 *
 * 你必须设计并实现一个只使用常量额外空间的算法来解决此问题。
 *
 * 不太理解下列的思路  不规定O(1) 用map就很简单了
 **/
public class 压缩字符串 {
    public static int compress(char[] chars) {
        int n = chars.length;
        int write = 0, left = 0;
        for (int read = 0; read < n; read++) {
            if (read == n - 1 || chars[read] != chars[read + 1]) {
                chars[write++] = chars[read];
                int num = read - left + 1;
                if (num > 1) {
                    int anchor = write;
                    while (num > 0) {
                        chars[write++] = (char) (num % 10 + '0');
                        num /= 10;
                    }
                    reverse(chars, anchor, write - 1);
                }
                left = read + 1;
            }
        }
        return write;
    }
    public static int compress2(char[] chars) {
        int index = 0; // 压缩后字符在数组中的索引位置
        int count = 1; // 当前字符的重复次数

        for (int i = 1; i <= chars.length; i++) {
            // 当前字符与前一个字符相同，增加重复次数
            if (i < chars.length && chars[i] == chars[i - 1]) {
                count++;
            }

            // 当前字符与前一个字符不同或到达数组末尾，进行压缩
            if (i == chars.length || chars[i] != chars[i - 1]) {
                chars[index++] = chars[i - 1]; // 压缩后的字符

                if (count > 1) {
                    // 重复次数大于1，将重复次数转换为字符并压缩
                    String countString = String.valueOf(count);
                    for (char c : countString.toCharArray()) {
                        chars[index++] = c;
                    }
                }

                count = 1; // 重置重复次数
            }
        }

        return index;
    }

    public static void reverse(char[] chars, int left, int right) {
        while (left < right) {
            char temp = chars[left];
            chars[left] = chars[right];
            chars[right] = temp;
            left++;
            right--;
        }
    }

    public static void main(String[] args) {
        char[] chars = {'a', 'a', 'b', 'b', 'c', 'c', 'c'};
        int newLength = compress(chars);
        System.out.println(newLength); // 输出 6

        // 打印压缩后的字符数组
        for (int i = 0; i < newLength; i++) {
            System.out.print(chars[i] + " ");
        }
    }
}
